home *** CD-ROM | disk | FTP | other *** search
- /* Generic device functions.
- Copyright (C) 1994, 1995 Board of Trustees, University of Illinois
- Copyright (C) 1994, 1995 Amdahl Corporation
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Not in FSF. */
-
- /* Original version by Chuck Thompson;
- rewritten by Ben Wing. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "buffer.h"
- #include "device.h"
- #include "elhash.h"
- #include "events.h"
- #include "faces.h"
- #include "frame.h"
- #include "keymap.h"
- #include "redisplay.h"
- #include "scrollbar.h"
- #include "specifier.h"
- #include "window.h"
-
- #include "syssignal.h"
-
- /* Vdefault_device is the firstly-created non-stream device that's still
- around. We don't really use it anywhere currently, but it might
- be used for resourcing at some point. (Currently we use
- Vdefault_x_device.) */
- Lisp_Object Vdefault_device;
-
- Lisp_Object Vdevice_list, Vselected_device;
-
- Lisp_Object Vcreate_device_hook, Vdelete_device_hook;
-
- /* Device classes */
- /* Qcolor defined in general.c */
- Lisp_Object Qgrayscale, Qmono;
-
- Lisp_Object Qdevicep, Qdevice_live_p;
- Lisp_Object Qdelete_device;
- Lisp_Object Qcreate_device_hook;
- Lisp_Object Qdelete_device_hook;
-
- DEFINE_DEVICE_TYPE (dead);
-
- Lisp_Object Vdevice_class_list;
- Lisp_Object Vdevice_type_list;
-
- MAC_DEFINE (struct device *, mactemp_device_data);
- MAC_DEFINE (struct device_methods *, mactemp_devtype_meth_or_given);
-
- struct device_type_entry
- {
- Lisp_Object symbol;
- struct device_methods *meths;
- };
-
- typedef struct device_type_entry_dynarr_type
- {
- Dynarr_declare (struct device_type_entry);
- } device_type_entry_dynarr;
-
- device_type_entry_dynarr *the_device_type_entry_dynarr;
-
-
-
- static Lisp_Object mark_device (Lisp_Object, void (*) (Lisp_Object));
- static void print_device (Lisp_Object, Lisp_Object, int);
- DEFINE_LRECORD_IMPLEMENTATION ("device", device,
- mark_device, print_device, 0, 0, 0,
- struct device);
-
- static Lisp_Object
- mark_device (Lisp_Object obj, void (*markobj) (Lisp_Object))
- {
- struct device *d = XDEVICE (obj);
-
- ((markobj) (d->name));
- ((markobj) (d->selected_frame));
- ((markobj) (d->frame_with_focus));
- ((markobj) (d->frame_that_ought_to_have_focus));
- ((markobj) (d->device_class));
- ((markobj) (d->function_key_map));
- ((markobj) (d->user_defined_tags));
- ((markobj) (d->pixel_to_glyph_cache.obj));
-
- ((markobj) (d->color_instance_cache));
- ((markobj) (d->font_instance_cache));
- ((markobj) (d->image_instance_cache));
-
- if (d->methods)
- ((markobj) (d->methods->symbol));
- MAYBE_DEVMETH (d, mark_device, (d, markobj));
-
- return (d->frame_list);
- }
-
- static void
- print_device (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
- {
- struct device *d = XDEVICE (obj);
- char buf[256];
-
- if (print_readably)
- error ("printing unreadable object #<device %s 0x%x>",
- string_data (XSTRING (d->name)), d->header.uid);
-
- sprintf (buf, "#<%s-device ", !DEVICE_LIVE_P (d) ? "dead" :
- DEVICE_TYPE_NAME (d));
- write_c_string (buf, printcharfun);
- print_internal (DEVICE_NAME (d), printcharfun, 1);
- sprintf (buf, " 0x%x>", d->header.uid);
- write_c_string (buf, printcharfun);
- }
-
-
- int
- valid_device_class_p (Lisp_Object class)
- {
- return !NILP (memq_no_quit (class, Vdevice_class_list));
- }
-
- struct device_methods *
- decode_device_type (Lisp_Object type, int no_error)
- {
- int i;
-
- for (i = 0; i < Dynarr_length (the_device_type_entry_dynarr); i++)
- {
- if (EQ (type, Dynarr_at (the_device_type_entry_dynarr, i).symbol))
- return Dynarr_at (the_device_type_entry_dynarr, i).meths;
- }
-
- if (!no_error)
- signal_simple_error ("Invalid device type", type);
-
- return 0;
- }
-
- int
- valid_device_type_p (Lisp_Object type)
- {
- if (decode_device_type (type, 1))
- return 1;
- return 0;
- }
-
- DEFUN ("valid-device-class-p", Fvalid_device_class_p, Svalid_device_class_p,
- 1, 1, 0,
- "Given a DEVICE-CLASS, return t if it is valid.\n\
- Valid classes are 'color, 'grayscale, and 'mono.")
- (device_class)
- Lisp_Object device_class;
- {
- if (valid_device_class_p (device_class))
- return Qt;
- else
- return Qnil;
- }
-
- DEFUN ("valid-device-type-p", Fvalid_device_type_p, Svalid_device_type_p,
- 1, 1, 0,
- "Given a DEVICE-TYPE, return t if it is valid.\n\
- Valid types are 'x, 'tty, and 'stream.")
- (device_type)
- Lisp_Object device_type;
- {
- if (valid_device_type_p (device_type))
- return Qt;
- else
- return Qnil;
- }
-
- DEFUN ("device-class-list", Fdevice_class_list, Sdevice_class_list,
- 0, 0, 0,
- "Return a list of valid device classes.")
- ()
- {
- return Fcopy_sequence (Vdevice_class_list);
- }
-
- DEFUN ("device-type-list", Fdevice_type_list, Sdevice_type_list,
- 0, 0, 0,
- "Return a list of valid device types.")
- ()
- {
- return Fcopy_sequence (Vdevice_type_list);
- }
-
- static struct device *
- allocate_device (void)
- {
- Lisp_Object device = Qnil;
- struct device *d = alloc_lcrecord (sizeof (struct device), lrecord_device);
-
- zero_lcrecord (d);
- XSETDEVICE (device, d);
-
- d->name = Qnil;
- d->frame_list = Qnil;
- d->selected_frame = Qnil;
- d->frame_with_focus = Qnil;
- d->frame_that_ought_to_have_focus = Qnil;
- d->device_class = Qnil;
- d->function_key_map = Qnil;
- d->user_defined_tags = Qnil;
- d->pixel_to_glyph_cache.obj = Qnil;
-
- d->infd = d->outfd = -1;
-
- /* #### is 20 reasonable? */
- d->color_instance_cache = make_lisp_hashtable (20, lisp_string_equal,
- lisp_string_hash,
- HASHTABLE_KEY_WEAK);
- d->font_instance_cache = make_lisp_hashtable (20, lisp_string_equal,
- lisp_string_hash,
- HASHTABLE_KEY_WEAK);
- /*
- Note that the image instance cache is actually bi-level.
- See device.h. We use a low number here because most of the
- time there aren't very many diferent masks that will be used.
- */
- d->image_instance_cache = make_lisp_hashtable (5, 0, 0,
- HASHTABLE_NONWEAK);
-
- d->quit_char = 7; /* C-g */
-
- return d;
- }
-
- struct device *
- get_device (Lisp_Object device)
- {
- if (NILP (device))
- device = Fselected_device ();
- /* quietly accept frames for the device arg */
- if (FRAMEP (device))
- {
- CHECK_LIVE_FRAME (device, 0);
- device = XFRAME (device)->device;
- }
- else
- {
- CHECK_LIVE_DEVICE (device, 0);
- }
- return XDEVICE (device);
- }
-
- DEFUN ("dfw-device", Fdfw_device, Sdfw_device, 1, 1, 0,
- "Given a device, frame, or window, return the associated device.\n\
- Return nil otherwise.")
- (obj)
- Lisp_Object obj;
- {
- return DFW_DEVICE (obj);
- }
-
-
- DEFUN ("selected-device", Fselected_device, Sselected_device, 0, 0, 0,
- "Return the device which is currently active.")
- ()
- {
- return Vselected_device;
- }
-
- /* Called from selected_frame_1(), called from Fselect_window() */
- void
- select_device_1 (Lisp_Object device)
- {
- /* perhaps this should do something more complicated */
- Vselected_device = device;
-
- /* #### Schedule this to be removed in 19.14 */
- #ifdef HAVE_X_WINDOWS
- if (DEVICE_IS_X (XDEVICE (device)))
- Vwindow_system = Qx;
- else
- #endif
- #ifdef HAVE_NEXTSTEP
- if (DEVICE_IS_NS (XDEVICE (device)))
- Vwindow_system = Qns;
- else
- #endif
- Vwindow_system = Qnil;
- }
-
- DEFUN ("select-device", Fselect_device, Sselect_device, 1, 1, 0,
- "Select the device DEVICE.\n\
- Subsequent editing commands apply to its selected frame and selected window.\n\
- The selection of DEVICE lasts until the next time the user does\n\
- something to select a different device, or until the next time this\n\
- function is called.")
- (device)
- Lisp_Object device;
- {
- CHECK_LIVE_DEVICE (device, 0);
-
- /* select the device's selected frame's selected window. This will call
- selected_frame_1(). */
- if (!NILP (DEVICE_SELECTED_FRAME (XDEVICE (device))))
- Fselect_window (FRAME_SELECTED_WINDOW (XFRAME (DEVICE_SELECTED_FRAME (XDEVICE (device)))));
- else
- error ("Can't select a device with no frames");
- return Qnil;
- }
-
- DEFUN ("devicep", Fdevicep, Sdevicep, 1, 1, 0,
- "Return non-nil if OBJECT is a device.")
- (object)
- Lisp_Object object;
- {
- if (!DEVICEP (object))
- return Qnil;
- return Qt;
- }
-
- DEFUN ("device-live-p", Fdevice_live_p, Sdevice_live_p, 1, 1, 0,
- "Return non-nil if OBJECT is a device that has not been deleted.")
- (object)
- Lisp_Object object;
- {
- if (!DEVICEP (object) || !DEVICE_LIVE_P (XDEVICE (object)))
- return Qnil;
- return Qt;
- }
-
- DEFUN ("device-type", Fdevice_type, Sdevice_type, 0, 1, 0,
- "Return the type of the specified device (e.g. `x' or `tty').\n\
- Value is `tty' for a tty device (a character-only terminal),\n\
- `x' for a device which is a connection to an X server,\n\
- `stream' for a stream device (which acts like a stdio stream), and\n\
- `dead' for a deleted device.")
- (device)
- Lisp_Object device;
- {
- /* don't call get_device() because we want to allow for dead devices. */
- if (NILP (device))
- device = Fselected_device ();
- CHECK_DEVICE (device, 0);
- return DEVICE_TYPE (XDEVICE (device));
- }
-
- DEFUN ("device-name", Fdevice_name, Sdevice_name, 0, 1, 0,
- "Return the name of the specified device.")
- (device)
- Lisp_Object device;
- {
- return DEVICE_NAME (get_device (device));
- }
-
- #ifdef HAVE_X_WINDOWS
- extern Lisp_Object Vdefault_x_device;
- #endif
- #ifdef HAVE_NEXTSTEP
- extern Lisp_Object Vdefault_ns_device;
- #endif
-
- static void
- init_global_resources (struct device *d)
- {
- init_global_faces (d);
- init_global_scrollbars (d);
- init_global_toolbars (d);
- }
-
- static void
- init_device_resources (struct device *d)
- {
- init_device_faces (d);
- init_device_scrollbars (d);
- init_device_toolbars (d);
- }
-
- DEFUN ("make-device", Fmake_device, Smake_device, 1, 2, 0,
- "Create a new device of type TYPE.\n\
- PARAMS, if specified, should be an alist of parameters controlling\n\
- device creation.")
- (type, params)
- Lisp_Object type, params;
- {
- /* This function can GC */
- struct device *d;
- Lisp_Object device = Qnil;
- struct gcpro gcpro1;
- #ifdef HAVE_X_WINDOWS
- /* #### icky-poo. If this is the first X device we are creating,
- then retrieve the global face resources. We have to do it
- here, at the same time as (or just before) the device face
- resources are retrieved; specifically, it needs to be done
- after the device has been created but before any frames have
- been popped up or much anything else has been done. It's
- possible for other devices to specify different global
- resources (there's a property on each X server's root window
- that holds some resources); tough luck for the moment.
-
- This is a nasty violation of device independence, but
- there's not a whole lot I can figure out to do about it.
- The real problem is that the concept of resources is not
- generalized away from X. Similar resource-related
- device-independence violations occur in faces.el. */
- int first_x_device = NILP (Vdefault_x_device) && EQ (type, Qx);
- #endif
-
- GCPRO1 (device);
-
- if (!valid_device_type_p (type))
- signal_simple_error ("Invalid device type", type);
-
- d = allocate_device ();
- XSETDEVICE (device, d);
-
- d->methods = decode_device_type (type, 0);
-
- DEVICE_NAME (d) = Fcdr_safe (Fassq (Qname, params));
- DEVMETH (d, init_device, (d, params));
-
- /* Do it this way so that the device list is in order of creation */
- Vdevice_list = nconc2 (Vdevice_list, Fcons (device, Qnil));
- RESET_CHANGED_SET_FLAGS;
- if (NILP (Vdefault_device) || DEVICE_IS_STREAM (XDEVICE (Vdefault_device)))
- Vdefault_device = device;
-
- init_device_sound (d);
- #ifdef HAVE_X_WINDOWS
- if (first_x_device)
- init_global_resources (d);
- #endif
- init_device_resources (d);
-
- if (DEVMETH (d, initially_selected_for_input, (d)))
- event_stream_select_device (d);
-
- /* #### the following should trap errors. However, if an error
- occurs, all that will happen is that the create-device-hook
- doesn't get run. */
- setup_device_initial_specifier_tags (d);
-
- run_hook_with_args (Qcreate_device_hook, 1, device);
-
- UNGCPRO;
- return device;
- }
-
- void
- add_entry_to_device_type_list (Lisp_Object symbol,
- struct device_methods *meths)
- {
- struct device_type_entry entry;
-
- entry.symbol = symbol;
- entry.meths = meths;
- Dynarr_add (the_device_type_entry_dynarr, entry);
- Vdevice_type_list = Fcons (symbol, Vdevice_type_list);
- }
-
- /* find a device other than the selected one. Prefer non-stream
- devices over stream devices. */
-
- static Lisp_Object
- find_other_device (Lisp_Object device)
- {
- Lisp_Object rest;
-
- /* look for a non-stream device */
- DEVICE_LOOP (rest)
- {
- Lisp_Object dev = XCAR (rest);
- if (!DEVICE_IS_STREAM (XDEVICE (dev)) && !EQ (dev, device) &&
- !NILP (DEVICE_SELECTED_FRAME (XDEVICE (dev))))
- break;
- }
- if (!NILP (rest))
- return XCAR (rest);
-
- /* OK, now look for a stream device */
- DEVICE_LOOP (rest)
- {
- Lisp_Object dev = XCAR (rest);
- if (!EQ (dev, device) && !NILP (DEVICE_SELECTED_FRAME (XDEVICE (dev))))
- break;
- }
- if (!NILP (rest))
- return XCAR (rest);
-
- /* Sorry, there ain't none */
- return Qnil;
- }
-
-
- DEFUN ("delete-device", Fdelete_device, Sdelete_device, 1, 1, 0,
- "Delete DEVICE, permanently eliminating it from use.")
- (device)
- Lisp_Object device;
- {
- /* This function can GC */
- Lisp_Object rest;
- struct device *d;
- int from_io_error = 0;
-
- /* kludge: if the device argument is a cons whose car is Qunbound,
- we are being called as a result of an IO error on a device.
- If this is the last device, don't try to ask for confirmation. */
-
- if (CONSP (device) && UNBOUNDP (XCAR (device)))
- {
- from_io_error = 1;
- device = XCDR (device);
- }
-
- CHECK_DEVICE (device, 0);
- d = XDEVICE (device);
-
- /* OK to delete an already-deleted device. */
- if (!DEVICE_LIVE_P (d))
- return Qnil;
-
- /* If Vrun_hooks is nil, we are being called from shut_down_emacs().
- At the time this is called, we could be in some weird unstable
- state, so it's safest not to do most of the junk below. We're
- about to exit, so it doesn't matter anyway. */
- if (!NILP (Vrun_hooks))
- {
- run_hook_with_args (Qdelete_device_hook, 1, device);
-
- if ((XINT (Flength (Vdevice_list)) == 1)
- && !NILP (memq_no_quit (device, Vdevice_list)))
- {
- if (from_io_error)
- {
- /* Mayday mayday! We're going down! */
- stderr_out (" Autosaving and exiting...\n");
- Vwindow_system = Qnil; /* let it lie! */
- Fset (Qkill_emacs_hook, Qnil); /* too dangerous */
- Fkill_emacs (make_number (70));
- }
- else
- call0 (Qsave_buffers_kill_emacs);
- }
-
- for (rest = DEVICE_FRAME_LIST (d); !NILP (rest);
- rest = XCDR (rest))
- {
- if (!FRAMEP (XCAR (rest)))
- continue;
- delete_frame_internal (XCAR (rest), 1);
- }
-
- DEVICE_SELECTED_FRAME (d) = Qnil;
-
- /* try to select another device */
-
- if (EQ (device, Fselected_device ()))
- {
- Lisp_Object other_dev = find_other_device (device);
- if (!NILP (other_dev))
- Fselect_device (other_dev);
- else
- {
- /* necessary? */
- Vselected_device = Qnil;
- Vwindow_system = Qnil;
- }
- }
-
- if (EQ (device, Vdefault_device))
- Vdefault_device = find_other_device (device);
- }
-
- if (d->input_enabled)
- event_stream_unselect_device (d);
-
- DEVMETH (d, delete_device, (d));
-
- Vdevice_list = delq_no_quit (device, Vdevice_list);
- RESET_CHANGED_SET_FLAGS;
- d->methods = dead_device_methods;
-
- return Qnil;
- }
-
- DEFUN ("device-list", Fdevice_list, Sdevice_list, 0, 0, 0,
- "Return a list of all devices.")
- ()
- {
- return Fcopy_sequence (Vdevice_list);
- }
-
- DEFUN ("device-frame-list", Fdevice_frame_list, Sdevice_frame_list,
- 0, 1, 0,
- "Return a list of all frames on DEVICE.\n\
- If DEVICE is nil, the selected device will be used.")
- (device)
- Lisp_Object device;
- {
- return Fcopy_sequence (DEVICE_FRAME_LIST (get_device (device)));
- }
-
- DEFUN ("device-class", Fdevice_class, Sdevice_class,
- 0, 1, 0,
- "Return the class (color behavior) of DEVICE.\n\
- This will be one of 'color, 'grayscale, or 'mono.")
- (device)
- Lisp_Object device;
- {
- return DEVICE_CLASS (get_device (device));
- }
-
- DEFUN ("device-pixel-width", Fdevice_pixel_width, Sdevice_pixel_width,
- 0, 1, 0,
- "Return the width in pixels of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_pixel_width, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("device-pixel-height", Fdevice_pixel_height, Sdevice_pixel_height,
- 0, 1, 0,
- "Return the height in pixels of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_pixel_height, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("device-mm-width", Fdevice_mm_width, Sdevice_mm_width,
- 0, 1, 0,
- "Return the width in millimeters of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_mm_width, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("device-mm-height", Fdevice_mm_height, Sdevice_mm_height,
- 0, 1, 0,
- "Return the height in millimeters of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_mm_height, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("device-bitplanes", Fdevice_bitplanes, Sdevice_bitplanes,
- 0, 1, 0,
- "Return the number of bitplanes of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_bitplanes, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("device-color-cells", Fdevice_color_cells, Sdevice_color_cells,
- 0, 1, 0,
- "Return the number of color cells of DEVICE, or nil if unknown.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- int retval;
-
- retval = DEVMETH_OR_GIVEN (d, device_color_cells, (d), 0);
- if (retval <= 0)
- return Qnil;
-
- return make_number (retval);
- }
-
- DEFUN ("set-device-baud-rate", Fset_device_baud_rate, Sset_device_baud_rate,
- 2, 2, 0,
- "Set the output baud rate of DEVICE to RATE.\n\
- On most systems, changing this value will affect the amount of padding\n\
- and other strategic decisions made during redisplay.")
- (device, rate)
- Lisp_Object device, rate;
- {
- CHECK_INT (rate, 0);
-
- DEVICE_BAUD_RATE (get_device (device)) = XINT (rate);
-
- return rate;
- }
-
- DEFUN ("device-baud-rate", Fdevice_baud_rate, Sdevice_baud_rate,
- 0, 1, 0,
- "Return the output baud rate of DEVICE.")
- (device)
- Lisp_Object device;
- {
- return make_number (DEVICE_BAUD_RATE (get_device (device)));
- }
-
- DEFUN ("device-enable-input", Fdevice_enable_input, Sdevice_enable_input,
- 1, 1, 0,
- "Enable input on device DEVICE.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- if (!d->input_enabled)
- event_stream_select_device (d);
- return Qnil;
- }
-
- DEFUN ("device-disable-input", Fdevice_disable_input, Sdevice_disable_input,
- 1, 1, 0,
- "Disable input on device DEVICE.")
- (device)
- Lisp_Object device;
- {
- struct device *d = get_device (device);
- if (d->input_enabled)
- event_stream_unselect_device (d);
- return Qnil;
- }
-
- /* #### These make a good case for adding at least some per-device
- variables. */
- DEFUN ("device-function-key-map", Fdevice_function_key_map,
- Sdevice_function_key_map, 0, 1, 0,
- "Return the function key mapping for DEVICE.")
- (device)
- Lisp_Object device;
- {
- return DEVICE_FUNCTION_KEY_MAP (get_device (device));
- }
-
- DEFUN ("set-device-function-key-map", Fset_device_function_key_map,
- Sset_device_function_key_map, 2, 2, 0,
- "Set the function key mapping for DEVICE to KEYMAP.")
- (device, keymap)
- Lisp_Object device, keymap;
- {
- struct device *d = get_device (device);
-
- CHECK_KEYMAP (keymap, 0);
- d->function_key_map = keymap;
- return keymap;
- }
-
- void
- handle_asynch_device_change (void)
- {
- int i;
- int old_asynch_device_change_pending = asynch_device_change_pending;
- for (i = 0; i < Dynarr_length (the_device_type_entry_dynarr); i++)
- {
- if (Dynarr_at (the_device_type_entry_dynarr, i).meths->
- asynch_device_change_method)
- (Dynarr_at (the_device_type_entry_dynarr, i).meths->
- asynch_device_change_method) ();
- }
- /* reset the flag to 0 unless another notification occurred while
- we were processing this one. Block SIGWINCH during this
- check to prevent a possible race condition. */
- EMACS_BLOCK_SIGNAL (SIGWINCH);
- if (old_asynch_device_change_pending == asynch_device_change_pending)
- asynch_device_change_pending = 0;
- EMACS_UNBLOCK_SIGNAL (SIGWINCH);
- }
-
- void
- call_critical_lisp_code (struct device *d, Lisp_Object function,
- Lisp_Object object)
- {
- int old_gc_currently_forbidden = gc_currently_forbidden;
- Lisp_Object old_inhibit_quit = Vinhibit_quit;
-
- /* There's no reason to bother doing specbinds here, because if
- initialize-*-faces signals an error, emacs is going to crash
- immediately.
- */
- gc_currently_forbidden = 1;
- Vinhibit_quit = Qt;
- LOCK_DEVICE (d);
-
- /* But it's useful to have an error handler; otherwise an infinite
- loop may result. */
- if (!NILP (object))
- call1_with_handler (Qreally_early_error_handler, function, object);
- else
- call0_with_handler (Qreally_early_error_handler, function);
-
- UNLOCK_DEVICE (d);
- Vinhibit_quit = old_inhibit_quit;
- gc_currently_forbidden = old_gc_currently_forbidden;
- }
-
-
- /************************************************************************/
- /* initialization */
- /************************************************************************/
-
- void
- syms_of_device (void)
- {
- defsubr (&Svalid_device_class_p);
- defsubr (&Svalid_device_type_p);
- defsubr (&Sdevice_class_list);
- defsubr (&Sdevice_type_list);
-
- defsubr (&Sdfw_device);
- defsubr (&Sselected_device);
- defsubr (&Sselect_device);
- defsubr (&Sdevicep);
- defsubr (&Sdevice_live_p);
- defsubr (&Sdevice_type);
- defsubr (&Sdevice_name);
- defsubr (&Smake_device);
- defsubr (&Sdelete_device);
- defsubr (&Sdevice_list);
- defsubr (&Sdevice_frame_list);
- defsubr (&Sdevice_class);
- defsubr (&Sdevice_pixel_width);
- defsubr (&Sdevice_pixel_height);
- defsubr (&Sdevice_mm_width);
- defsubr (&Sdevice_mm_height);
- defsubr (&Sdevice_bitplanes);
- defsubr (&Sdevice_color_cells);
- defsubr (&Sset_device_baud_rate);
- defsubr (&Sdevice_baud_rate);
- defsubr (&Sdevice_enable_input);
- defsubr (&Sdevice_disable_input);
- defsubr (&Sdevice_function_key_map);
- defsubr (&Sset_device_function_key_map);
-
- defsymbol (&Qdevicep, "devicep");
- defsymbol (&Qdevice_live_p, "device-live-p");
- defsymbol (&Qdelete_device, "delete-device");
-
- defsymbol (&Qcreate_device_hook, "create-device-hook");
- defsymbol (&Qdelete_device_hook, "delete-device-hook");
-
- /* Qcolor defined in general.c */
- defsymbol (&Qgrayscale, "grayscale");
- defsymbol (&Qmono, "mono");
- }
-
- void
- device_type_create (void)
- {
- the_device_type_entry_dynarr = Dynarr_new (struct device_type_entry);
-
- Vdevice_type_list = Qnil;
- staticpro (&Vdevice_type_list);
-
- /* Initialize the dead device type */
- INITIALIZE_DEVICE_TYPE (dead, "dead", "device-dead-p");
-
- /* then reset the device-type lists, because `dead' is not really
- a valid device type */
- Dynarr_reset (the_device_type_entry_dynarr);
- Vdevice_type_list = Qnil;
- }
-
- void
- vars_of_device (void)
- {
- DEFVAR_LISP ("create-device-hook", &Vcreate_device_hook,
- "Function or functions to call when a device is created.\n\
- One argument, the newly-created device.\n\
- Note that the device will not be selected and will not have any\n\
- frames on it.");
- Vcreate_device_hook = Qnil;
-
- DEFVAR_LISP ("delete-device-hook", &Vdelete_device_hook,
- "Function or functions to call when a device is deleted.\n\
- One argument, the to-be-deleted device.");
- Vdelete_device_hook = Qnil;
-
- staticpro (&Vdevice_list);
- Vdevice_list = Qnil;
- staticpro (&Vselected_device);
- Vselected_device = Qnil;
- staticpro (&Vdefault_device);
- Vdefault_device = Qnil;
-
- asynch_device_change_pending = 0;
-
- Vdevice_class_list = list3 (Qcolor, Qgrayscale, Qmono);
- staticpro (&Vdevice_class_list);
- }
-